﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
// std headers

// qt headers
#include <QIcon>
#include <QListWidget>
#include <QScrollBar>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QStackedLayout>
#include <QFrame>
#include <QFontMetrics>
#include <QObject>
#include <QEvent>
#include <QWidgetAction>

// gcmp headers
#include "StringUtil.h"
#include "LogManager.h"

#include "TranslatorManager.h"
#include "GbmpNew.h"

// custom headers
#include "BaseCommonUtils.h"

#include "LegendChoosingDialog.h"
#include "CustomReply.h"
#include "IPagedData.h"
#include "PropertyService.h"
#include "CustomFileReply.h"
#include "AppService.h"
#include "PathUtils.h"
#include "ProjectCloudComponentService.h"
#include "ProjectLocalComponentService.h"
#include "DebugMode.h"
#include "BottomLineTab.h"
#include "GncINetworkCheck.h"
#include "GmepVersionUtils.h"
#include "GnufMessageBoardInterface.h"

#include "EnableCompileWarning_The_LAST_IncludeInCpp.h" 

#define  LEGENDLIST_INDEX 0
#define  NO_LEGEND_GUIDE_INDEX 1
#define  NO_NETWORK_GUIDE_INDEX 2

namespace gmepgcs
{
    LegendChoosingDialog::LegendChoosingDialog(QWidget *parent, Qt::WindowFlags flags) :
        MessageDialog(parent, flags),
        m_categoryCode(),
        m_categoryUid(),
        m_projectId(),
        m_enterpriseId(),
        m_legendType(ILegend::LegendType::Invalid),
        m_pageSize(500),
        m_errorMessage()
    {
        UiState = FromLocal;
        m_LegendsListWidget = nullptr;
        m_ContentGuideWidget = nullptr;
        m_ContentImageLabel = nullptr;
        m_ContentText = nullptr;
        m_LoadInBtn = nullptr;
        m_LoadInMenu = nullptr;
        OkBtn = nullptr;
        m_vCurrLegends = std::vector<std::shared_ptr<ILegend>>();
        m_vLocalLegends = std::vector<std::shared_ptr<ILegend>>();
        m_vPublicLegends = std::vector<std::shared_ptr<ILegend>>();
        m_vEnterpriseLegends = std::vector<std::shared_ptr<ILegend>>();
        m_chosenLegend = nullptr;

        Init();
    }

    LegendChoosingDialog::~LegendChoosingDialog()
    {
    }

    MessageDialog::MessageDialogResult LegendChoosingDialog::Show(
        const std::wstring &projectId,
        const std::wstring &enterpeiseId,
        const std::wstring & categoryCode,
        const std::wstring &categoryUid,
        const bool isPrivateEnv,
        const ILegend::LegendType &legendType,
        std::shared_ptr<ILegend> &chosenLegend,
        QWidget * parent)
    {
        LegendChoosingDialog *pDialog = LegendChoosingDialog::Get(parent);
        if (!pDialog)
        {
            return LegendChoosingDialog::MessageDialogResult::ResultNotSet;
        }

        pDialog->Resume();

        const std::wstring title = GBMP_TR(L"选择") + ILegend::GetTypeName(legendType);
        pDialog->setWindowTitle(QString::fromStdWString(title));

        pDialog->m_projectId = projectId;
        pDialog->m_enterpriseId = enterpeiseId;
        pDialog->m_categoryCode = categoryCode;
        pDialog->m_categoryUid = categoryUid;
        pDialog->m_legendType = legendType;
        pDialog->m_chosenLegend = chosenLegend;
        pDialog->m_isPrivateEnv = isPrivateEnv;

        pDialog->SetCenterContentUI(FromLocal);
        pDialog->exec();

        MessageDialog::MessageDialogResult result = pDialog->GetDialogResult();
        pDialog->AddChosenLegendToLocal();
        chosenLegend = pDialog->GetChosenLegend();

        pDialog->ClearLegendListWidget();

        return result;
    }


    LegendChoosingDialog * LegendChoosingDialog::s_pInstance;
    LegendChoosingDialog * LegendChoosingDialog::Get(QWidget *parent)
    {
        if (!LegendChoosingDialog::s_pInstance)
        {
            LegendChoosingDialog::s_pInstance = NEW_AS_QT(LegendChoosingDialog, parent);
            LegendChoosingDialog::s_pInstance->setObjectName("LegendChoosingDialog");
        }
        else if (LegendChoosingDialog::s_pInstance->parentWidget() != parent)
        {
            LegendChoosingDialog::s_pInstance->deleteLater();
            LegendChoosingDialog::s_pInstance = NEW_AS_QT(LegendChoosingDialog, parent);
            LegendChoosingDialog::s_pInstance->setObjectName("LegendChoosingDialog");
        }
        return LegendChoosingDialog::s_pInstance;
    }

    void LegendChoosingDialog::Init()
    {
        // dialog self
        setFixedSize(480, 408);
        setWindowIcon(QIcon());
        SetButtons(MessageDialogButton::BtnCancel | MessageDialogButton::BtnOk);
        setModal(true);

        //Search Txt
        {
            SearchTxt = NEW_AS_QT(SearchTextBox, QString::fromStdWString(GBMP_TR(L"输入关键词或短语查找构件")), this);
            DBG_WARN_AND_RETURN_VOID_UNLESS(SearchTxt, L"SearchTxt为空", L"GMEP", L"2024-01-30");
            SearchTxt->setObjectName("SearchTxt");
            SearchTxt->setGeometry(QRect(16, 40, 440, 20));
            SearchTxt->setFixedWidth(440);
            connect(SearchTxt, &SearchTextBox::Searched, this, &LegendChoosingDialog::OnSearchBtnClick);
            connect(SearchTxt, &SearchTextBox::textChanged, this, &LegendChoosingDialog::OnSearchBtnClick);
        }

        // legend list图例库
        {
            m_LegendsListWidget = NEW_AS_QT(QListWidget, this);
            DBG_WARN_AND_RETURN_VOID_UNLESS(m_LegendsListWidget, L"m_LegendsListWidget为空", L"GMEP", L"2024-01-30");
            m_LegendsListWidget->setGeometry(QRect(0, 74, 480, 290));
            m_LegendsListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
            m_LegendsListWidget->setViewMode(QListView::ViewMode::IconMode);
            m_LegendsListWidget->setIconSize(QSize(200, 216));
            m_LegendsListWidget->setSpacing(16);
            m_LegendsListWidget->setResizeMode(QListWidget::ResizeMode::Adjust);
            m_LegendsListWidget->setMovement(QListWidget::Movement::Static);
            m_LegendsListWidget->setSelectionMode(QListWidget::SelectionMode::SingleSelection);
            m_LegendsListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
            m_LegendsListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
            m_LegendsListWidget->setObjectName("LocalLegendsListWidget");
            m_LegendsListWidget->setStyleSheet(
                "QListWidget#LocalLegendsListWidget{"
                "border:none;"
                "background:transparent;"
                "}"
                "QListWidget::Item{"
                "background:transparent;"
                "border:none;"
                "padding:0px"
                "}"
                "QListWidget::Item:selected{"
                "background:transparent;"
                "}"
            );
            QScrollBar* pScrollBar = m_LegendsListWidget->verticalScrollBar();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pScrollBar, L"pScrollBar为空", L"GMEP", L"2024-01-30");
            pScrollBar->setStyleSheet(
                "QScrollBar:vertical{"
                "width:8px;"
                "background:rgba(0,0,0,0%);"
                "margin:0px,0px,0px,0px;"
                "padding-top:0px;"
                "padding-bottom:0px;"
                "padding-left:1px;"
                "padding-right:1px;"
                "}"
                "QScrollBar::handle:vertical{"
                "width:6px;"
                "background:rgba(35,40,50,20%);"
                "border-radius:2px;"
                "min-height:20;"
                "}"
                "QScrollBar::handle:vertical:hover{"
                "width:6px;"
                "background:rgba(35,40,50,40%);"
                " border-radius:2px;"
                "min-height:20;"
                "}"
                "QScrollBar::add-line:vertical{"
                "height:0px;width:0px;"
                "border-image:url(:/images/icon_triangle_solid_down_8.png);"
                "subcontrol-position:bottom;"
                "}"
                "QScrollBar::sub-line:vertical{"
                "height:0px;width:0px;"
                "border-image:url(:/images/icon_triangle_solid_up_8.png);"
                "subcontrol-position:top;"
                "}"
                "QScrollBar::add-line:vertical:hover{"
                "height:0px;width:0px;"
                "border-image:url(:/images/icon_triangle_solid_down_8.png);"
                "subcontrol-position:bottom;"
                "}"
                "QScrollBar::sub-line:vertical:hover{"
                "height:0px;width:0px;"
                "border-image:url(:/images/icon_triangle_solid_up_8.png);"
                "subcontrol-position:top;"
                "}"
                "QScrollBar::add-page:vertical,QScrollBar::sub-page:vertical{"
                "background:rgba(255,255,255,10%);"
                "border-radius:4px;"
                "}"
            );
            bool bSucc = connect(m_LegendsListWidget, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)), this, SLOT(OnLegendItemChanged(QListWidgetItem *, QListWidgetItem *)));
            DBG_WARN_UNLESS(bSucc, L"bSucc 为false", L"GMEP", L"2024-01-30");
        }

        // 引导页
        {
            m_ContentGuideWidget = NEW_AS_QT(QWidget, this);
            DBG_WARN_AND_RETURN_VOID_UNLESS(m_ContentGuideWidget, L"m_ContentGuideWidget为空", L"GMEP", L"2024-01-30");
            m_ContentGuideWidget->setObjectName("Localm_NoContentGuideWidget");
            m_ContentGuideWidget->setContentsMargins(0, 0, 0, 0);
            m_ContentGuideWidget->setGeometry(QRect(0, 74, 480, 290));
            QLayout* pNoContentGuideViewLayout = InitContentGuideView(m_ContentGuideWidget);
            DBG_WARN_UNLESS(pNoContentGuideViewLayout, L"引导页空", L"GMEP", L"2024-01-30");
            pNoContentGuideViewLayout->setAlignment(Qt::AlignHCenter);
        }

        // ok button
        {
            OkBtn = GetButton(MessageDialogButton::BtnOk);
            if (OkBtn)
            {
                OkBtn->setEnabled(false);
            }
        }

        //loadItem button and Menu
        {
            // 添加构件菜单
            m_LoadInMenu = NEW_AS_QT(QMenu, this);
            DBG_WARN_AND_RETURN_VOID_UNLESS(m_LoadInMenu != nullptr, L"m_LoadInMenu为空", L"GMEP", L"2024-01-30");
            m_LoadInMenu->setObjectName("LoadInMenu");
            m_LoadInMenu->setStyleSheet(
                "QMenu{"
                "background:rgba(255,255,255,255);"
                "border-top-left-radius:0px;"
                "border-top-right-radius:0px;"
                "border-bottom-right-radius:2px;"
                "border-bottom-left-radius:2px;"
                "border:1px solid rgba(217, 221, 228, 255);"
                "}"
                "QMenu::item{"
                "background:transparent;"
                "padding-top:5px;"
                "padding-bottom:5px;"
                "padding-left:5px;"
                "padding-right:5px;"
                "}"
            );

            QString menuItemStyle(
                "QPushButton{"
                "background:transparent;"
                "font-family:\"Microsoft YaHei\";"
                "font-size:12px;"
                "color:rgba(0,0,0,255);"
                "border:none;"
                "}"
                "QPushButton:hover{"
                "background:rgba(231, 242, 255, 255);"
                "}"
                "QPushButton::disabled{"
                "color:rgba(120, 122, 131,255);"
                "}"
            );

            // 从企业库
            QWidgetAction* pActionFromEnterprise = NEW_AS_QT_CHILD(QWidgetAction, m_LoadInMenu);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pActionFromEnterprise != nullptr, L"pActionFromEnterprise为空", L"GMEP", L"2024-01-30");
            QPushButton *pBtnFromEnterprise = NEW_AS_QT(QPushButton, QString::fromStdWString(GBMP_TR(L" 从企业库")));
            DBG_WARN_AND_RETURN_VOID_UNLESS(pBtnFromEnterprise != nullptr, L"pBtnFromEnterprise为空", L"GMEP", L"2024-01-30");
            pBtnFromEnterprise->setObjectName("pBtnFromEnterprise");
            pBtnFromEnterprise->setFixedWidth(68);
            pBtnFromEnterprise->setFixedHeight(24);
            pBtnFromEnterprise->setStyleSheet(menuItemStyle);
            pActionFromEnterprise->setDefaultWidget(pBtnFromEnterprise);
            m_LoadInMenu->addAction(pActionFromEnterprise);
            connect(pBtnFromEnterprise, &QPushButton::clicked, [=]() {
                m_LoadInMenu->hide();
                SetCenterContentUI(FromEnterprise);
                SetNewtWindowTitle(GBMP_TR(L"从企业库"));
            });

            // 从公共库
            QWidgetAction* pActionFromPublic = NEW_AS_QT(QWidgetAction, m_LoadInMenu);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pActionFromPublic != nullptr, L"pActionFromPublic为空", L"GMEP", L"2024-01-30");
            QPushButton *pBtnFromPublic = NEW_AS_QT(QPushButton, QString::fromStdWString(GBMP_TR(L" 从公共库")));
            DBG_WARN_AND_RETURN_VOID_UNLESS(pBtnFromPublic != nullptr, L"pBtnFromPublic为空", L"GMEP", L"2024-01-30");
            pBtnFromPublic->setObjectName("pBtnFromPublic");
            pBtnFromPublic->setFixedWidth(68);
            pBtnFromPublic->setFixedHeight(24);
            pBtnFromPublic->setStyleSheet(menuItemStyle);
            pActionFromPublic->setDefaultWidget(pBtnFromPublic);
            m_LoadInMenu->addAction(pActionFromPublic);
            connect(pBtnFromPublic, &QPushButton::clicked, [=]() {
                m_LoadInMenu->hide();
                gmepgcs::ProjectCloudComponentService* pService = gmepgcs::ProjectCloudComponentService::Get();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pService, L"pService 为空", L"GMEP", L"2024-01-30");
                // 无论公有云 私有化， 必须有外网才能访问公共图例库
                if (!gnc::INetworkCheck::Get() || !gnc::INetworkCheck::Get()->CheckNetworkConnection())
                {
                    gnuf::ShowMessageBoard(GBMP_TR(L"无法连接网络，请检查后重试 "), GBMP_TR(L"提示"), gnuf::eMB_OK | gnuf::eMB_ICONINFORMATION);
                    return;
                }
                // 若登录不成功，则返回，不再进行切换
                if (!pService->EnsureGjwLoggedIn())
                    return;
                //公共库
                SetCenterContentUI(FromPublic);
                SetNewtWindowTitle(GBMP_TR(L"从公共库"));
            });

            
            m_LoadInBtn = NEW_AS_QT(QPushButton, this);
            DBG_WARN_AND_RETURN_VOID_UNLESS(m_LoadInBtn, L"m_LoadInBtn为空", L"GMEP", L"2024-01-30");
            m_LoadInBtn->setGeometry(QRect(16, 366, 70, 26));
            m_LoadInBtn->setFixedWidth(70);
            m_LoadInBtn->setFixedHeight(26);
            m_LoadInBtn->setCursor(QCursor(Qt::CursorShape::PointingHandCursor));
            m_LoadInBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
            m_LoadInBtn->setText(QString::fromStdWString(GBMP_TR(L"添加图例")));
            m_LoadInBtn->setObjectName("m_LoadInBtn");
            m_LoadInBtn->setStyleSheet(QString(
                "background-color:rgba(245, 245, 245, 255);"
                "border:1px solid rgba(217, 221, 228, 255);"
                "border-radius:2px;"
                "font-family:Microsoft YaHei;"
                "font-size:12px;"
                "color:rgba(0,0,0,255);"
                "}"
            ));


            connect(m_LoadInBtn, &QPushButton::clicked, this, [=]()
            {
                if (m_LoadInMenu)
                    m_LoadInMenu->popup(mapToGlobal(m_LoadInBtn->geometry().bottomLeft()));
            });
        }
    }

    void LegendChoosingDialog::ClearLegendListWidget()
    {
        DBG_WARN_UNLESS(m_LegendsListWidget, L"m_LegendsListWidget 为空", L"GMEP", L"2024-01-30");

        m_LegendsListWidget->blockSignals(true);
        m_chosenLegend = nullptr;
        m_LegendsListWidget->clear();
        m_Thumbnails.clear();
        if (OkBtn)
        {
            OkBtn->setEnabled(false);
        }
        m_LegendsListWidget->blockSignals(false);
    }

    void LegendChoosingDialog::ShowLocalLegendContent()
    {
        if (m_vLocalLegends.empty())
        {
            // 从本地读
            PropertyService * pPropertyService = PropertyService::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pPropertyService, L"pPropertyService为空", L"GMEP", L"2024-01-30");
            const std::vector<std::shared_ptr<ILegend>> pAvailabelLegends = pPropertyService->GetLegends(m_categoryCode, m_legendType);
            for (auto &legend : pAvailabelLegends)
            {
                if (!legend)
                {
                    continue;
                }
                if (legend->PlaceholderFrom != 1)
                {
                    m_vLocalLegends.push_back(legend);
                }
            }
            if (m_vLocalLegends.empty() || pAvailabelLegends.empty())
            {
                SetCenterContentUI(NoItems);
                return;
            }
            else
            {
                // 填充
                FillLocalLegendIntoListWidget();
            }
        }
        else
        {
            // 填充
            FillLocalLegendIntoListWidget();
        }
    }
    void LegendChoosingDialog::ShowPublicLegendContent()
    {
        // 暂存没有，先获取
        if (m_vPublicLegends.empty() || m_vPublicLegends.empty())
        {
            // 若是公有云环境，则需要检查网络
            if (!gmep::GmepVersionUtils::IsPrivatizationEnvironment())
            {
                if (!gnc::INetworkCheck::Get() || !gnc::INetworkCheck::Get()->CheckNetworkConnection())
                {
                    SetCenterContentUI(NoNetWork);
                    return;
                }
            }

            auto pAvailabelLegendsReply = PropertyService::Get()->GetLegendsFromCloud(m_categoryCode, m_legendType, m_pageSize, 1, AppService::Get()->GeFormattedProductVersion());

            if (!pAvailabelLegendsReply)
            {
                m_errorMessage = QString::fromStdWString(GBMP_TR(L"从公共库获取可用的图例库失败"));
                SetCenterContentUI(NoItems);
                return;
            }
            else
            {
                connect(pAvailabelLegendsReply, &CustomReply<IPagedData<std::vector<std::shared_ptr<ILegend>>>>::Finished, [=]()
                {
                    if (!pAvailabelLegendsReply->Error().empty())
                    {
                        m_errorMessage = QString::fromStdWString(pAvailabelLegendsReply->Error());
                        pAvailabelLegendsReply->deleteLater();
                        SetCenterContentUI(NoItems);
                        return;
                    }
                    m_vPublicLegends = pAvailabelLegendsReply->Result().Data;
                    pAvailabelLegendsReply->deleteLater();
                    if (m_vPublicLegends.empty())
                    {
                        SetCenterContentUI(NoItems);
                        return;
                    }
                    else
                    {
                        // 填充UI控件
                        FillPublicLegendIntoListWidget();
                    }
                });
            }
        }
        else
        {
            // 填充UI控件
            FillPublicLegendIntoListWidget();
        }
    }
    void LegendChoosingDialog::ShowEnterpriseLegnedContent()
    {
        // 暂存没有，先获取
        if (m_vEnterpriseLegends.empty() || m_vEnterpriseLegends.size() == 0)
        {
            // 若是公有云环境，则需要检查网络
            if (!gmep::GmepVersionUtils::IsPrivatizationEnvironment())
            {
                if (!gnc::INetworkCheck::Get() || !gnc::INetworkCheck::Get()->CheckNetworkConnection())
                {
                    SetCenterContentUI(NoNetWork);
                    return;
                }
            }

            auto enterpriseLegends = PropertyService::Get()->GetLegendsFromEnterpriseCloudByHttpRespone(m_categoryUid, m_enterpriseId, m_legendType, m_pageSize, 1, AppService::Get()->GeFormattedProductVersion());

            if (enterpriseLegends.empty())
            {
                m_errorMessage = QString::fromStdWString(GBMP_TR(L"从企业库获取可用的图例库失败"));
                SetCenterContentUI(NoItems);
                return;
            }
            else
            {
                m_vEnterpriseLegends = enterpriseLegends;
                // 填充UI控件
                FillEnterpriseLegendIntoListWidget();
            }
        }
        else
        {
            // 填充UI控件
            FillEnterpriseLegendIntoListWidget();
        }
    }

    void LegendChoosingDialog::FillLocalLegendIntoListWidget()
    {
        DBG_WARN_UNLESS(!m_vLocalLegends.empty(), L"m_vLocalLegends 为空", L"GMEP", L"2024-01-30");
        m_vCurrLegends = m_vLocalLegends;
        FillLegendIntoListWidget(m_vCurrLegends);
    }

    void LegendChoosingDialog::FillPublicLegendIntoListWidget()
    {
        DBG_WARN_UNLESS(!m_vPublicLegends.empty(), L"m_vPublicLegends 为空", L"GMEP", L"2024-01-30");
        m_vCurrLegends = m_vPublicLegends;
        FillLegendIntoListWidget(m_vCurrLegends);
    }

    void LegendChoosingDialog::FillEnterpriseLegendIntoListWidget()
    {
        DBG_WARN_UNLESS(!m_vEnterpriseLegends.empty(), L"m_vEnterpriseLegends 为空", L"GMEP", L"2024-01-30");
        m_vCurrLegends = m_vEnterpriseLegends;
        FillLegendIntoListWidget(m_vCurrLegends);
    }

    void LegendChoosingDialog::FillLegendIntoListWidget(std::vector<std::shared_ptr<ILegend>>  setLgs)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_LegendsListWidget, L"m_LegendsListWidget为空", L"GMEP", L"2024-01-30");
        DBG_WARN_UNLESS(!setLgs.empty(), L"填充 list widget 图例集合 为空", L"GMEP", L"2024-01-30");
        bool isFromNet = UiState != FromLocal;
        m_LegendsListWidget->blockSignals(true);

        int itemNum = 0;
        for (auto &legend : setLgs)
        {
            if (!legend)
            {
                continue;
            }
            ++itemNum;
            QListWidgetItem *listItem = NEW_AS_QT(QListWidgetItem, m_LegendsListWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(listItem, L"listItem为空", L"GMEP", L"2024-01-30");
            listItem->setSizeHint(QSize(itemWidth, itemWidth + 16));
            std::wstring currentId = legend->PlaceholderFrom != 0 ? legend->Uid : gcmp::StringUtil::ToWString(legend->Id);
            listItem->setData(Qt::ItemDataRole::UserRole, QString::fromStdWString(currentId));
            //listItem->setData(Qt::ItemDataRole::ToolTipRole, QString::fromStdWString(legend->Name));
            m_LegendsListWidget->addItem(listItem);

            // item widget
            QFrame *pItemWidget = NEW_AS_QT(QFrame, m_LegendsListWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pItemWidget, L"pItemWidget为空", L"GMEP", L"2024-01-30");
            QString itemName = QString::fromStdWString(L"legned_Item_%1").arg(itemNum);
            pItemWidget->setObjectName(itemName);
            pItemWidget->setStyleSheet(
                QString(
                    "QFrame#%1{"
                    "border:1px solid rgba(217, 221, 228, 255);"
                    "border-radius:2px;"
                    "padding:1px;"
                    "}").arg(itemName)
            );
            m_LegendsListWidget->setItemWidget(listItem, pItemWidget);

            // stacked layout
            QStackedLayout *pStackedLayout = NEW_AS_QT(QStackedLayout, pItemWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pStackedLayout, L"pStackedLayout为空", L"GMEP", L"2024-01-30");
            pItemWidget->setLayout(pStackedLayout);
            pStackedLayout->setContentsMargins(0, 0, 0, 0);
            pStackedLayout->setSpacing(0);
            pStackedLayout->setStackingMode(QStackedLayout::StackingMode::StackAll);

            // selection mask
            QLabel *pLblSelectionMask = NEW_AS_QT(QLabel, pItemWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pLblSelectionMask, L"pLblSelectionMask为空", L"GMEP", L"2024-01-30");
            pStackedLayout->addWidget(pLblSelectionMask);
            QString selectionMaskName = "SelectionMask" + QString::fromStdWString(currentId);
            pLblSelectionMask->setObjectName(selectionMaskName);
            pLblSelectionMask->setStyleSheet("QLabel{background:rgba(41, 121, 255, 0.1 * 255);}");
            pLblSelectionMask->setVisible(false);

            // content widget
            QWidget *pContentWidget = NEW_AS_QT(QWidget, pItemWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pContentWidget, L"pContentWidget为空", L"GMEP", L"2024-01-30");
            pContentWidget->setObjectName(QString::fromStdWString(currentId));
            pContentWidget->setToolTip(QString::fromStdWString(legend->Name));
            pStackedLayout->addWidget(pContentWidget);

            // item layout
            QVBoxLayout *pContentLayout = NEW_AS_QT(QVBoxLayout, pItemWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pContentLayout, L"pContentLayout为空", L"GMEP", L"2024-01-30");
            pContentWidget->setLayout(pContentLayout);
            pContentLayout->setContentsMargins(0, 0, 0, 0);
            pContentLayout->setSpacing(0);

            // legend thumbnail label
            QLabel *pLblThumbnail = NEW_AS_QT(QLabel, pItemWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pLblThumbnail, L"pLblThumbnail为空", L"GMEP", L"2024-01-30");
            pLblThumbnail->setFixedSize(itemWidth, itemWidth - 14);
            QSize sz(itemWidth, itemWidth - 14);
            pContentLayout->addWidget(pLblThumbnail);
            pLblThumbnail->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Expanding);
            pLblThumbnail->setStyleSheet("QLabel{background:rgba(245,245, 245, 255);}");
            pLblThumbnail->setAlignment(Qt::AlignCenter);
            if (!legend->Thumbnail.empty())
            {
                if (isFromNet)
                {
                    CustomFileReply *pCustomReply = ProjectCloudComponentService::Get()->DownloadComponent
                    (legend->Thumbnail, PathUtils::GetThumbnailDownloadFilePath(legend->Thumbnail), (legend->PlaceholderFrom != 0 && legend->PlaceholderFrom != 1));
                    if (pCustomReply)
                    {
                        m_Thumbnails.push_back(pLblThumbnail);
                        connect(pCustomReply, &CustomFileReply::Finished, [=]
                        {
                            if (pCustomReply->Error().empty())
                            {
                                QPixmap pixmap;
                                pixmap.load(QString::fromStdWString(pCustomReply->GetSaveFilePath()));
                                DownLoadThumbnailSetBack(pLblThumbnail, pixmap);
                            }
                            else
                            {
                                DBG_WARN(pCustomReply->Error(), L"GMEP", L"2024-01-30");
                            }
                        });
                    }
                }
                else
                {
                    QPixmap pixmap;
                    pixmap.load(QString::fromStdWString(legend->Thumbnail));
                    pLblThumbnail->setPixmap(pixmap.scaled(sz, Qt::AspectRatioMode::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation));
                }
            }

            // legend name label
            QLabel *pLblName = NEW_AS_QT(QLabel, pItemWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pLblName, L"pLblName为空", L"GMEP", L"2024-01-30");
            pContentLayout->addWidget(pLblName);
            pContentLayout->setAlignment(pLblName, Qt::AlignBottom);
            pLblName->setMinimumHeight(30);
            pLblName->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);
            pLblName->setAlignment(Qt::AlignCenter);
            pLblName->setStyleSheet(
                "QLabel{"
                "background:rgba(245, 245, 245, 255);"
                "font-family:\"Microsoft YaHei\";"
                "font-size:12px;"
                "color:rgba(0,0,0,255);"
                "}"
            );

            QFontMetrics fontMetrics(pLblName->font());
            QString elidedText = fontMetrics.elidedText(QString::fromStdWString(legend->Name), Qt::TextElideMode::ElideRight, itemWidth);
            pLblName->setText(elidedText);
        }

        #pragma region  fakeitem  避免最后一个item下半部分点击无效情况
        QListWidgetItem *FakelistItem = NEW_AS_QT(QListWidgetItem, m_LegendsListWidget);
        int itemWidth = 96;
        DBG_WARN_AND_RETURN_VOID_UNLESS(FakelistItem, L"FakelistItem 为空", L"GMEP", L"2024-01-30");
        FakelistItem->setSizeHint(QSize(itemWidth, itemWidth + 16));
        m_LegendsListWidget->addItem(FakelistItem);
        QFrame *pItemWidget = NEW_AS_QT(QFrame, m_LegendsListWidget);
        DBG_WARN_AND_RETURN_VOID_UNLESS(pItemWidget, L"pItemWidget为空", L"GMEP", L"2024-01-30");
        QString itemName = QString::fromStdWString(L"Fake_Item");
        pItemWidget->setObjectName(itemName);
        pItemWidget->setStyleSheet(
            QString(
                "QFrame#%1{"
                "border:1px solid rgba(217, 221, 228, 255);"
                "border-radius:2px;"
                "padding:1px;"
                "}").arg(itemName)
        );
        m_LegendsListWidget->setItemWidget(FakelistItem, pItemWidget);
        FakelistItem->setHidden(true);
        #pragma endregion

        m_LegendsListWidget->blockSignals(false);
    }

    void LegendChoosingDialog::DownLoadThumbnailSetBack(QLabel * pLblThumbnail, QPixmap pixmap)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(pLblThumbnail, L"pLblThumbnail 为空", L"GMEP", L"2024-01-30");
        DBG_WARN_UNLESS(!pixmap.isNull(), L"pixmap为空", L"GMEP", L"2024-01-30");
        if (m_Thumbnails.contains(pLblThumbnail))
        {
            pLblThumbnail->setPixmap(pixmap.scaled(QSize(itemWidth, itemWidth - 14), Qt::AspectRatioMode::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation));
        }
    }

    void LegendChoosingDialog::SetCenterContentUI(ContentUIState state)
    {
        DBG_WARN_UNLESS(m_LegendsListWidget, L"m_LegendsListWidget 为空", L"GMEP", L"2024-01-30");
        DBG_WARN_UNLESS(m_ContentGuideWidget, L"m_ContentGuideWidget 为空", L"GMEP", L"2024-01-30");
        DBG_WARN_UNLESS(m_ContentImageLabel, L"m_ContentImageLabel 为空", L"GMEP", L"2024-01-30");
        DBG_WARN_UNLESS(m_ContentText, L"m_ContentText 为空", L"GMEP", L"2024-01-30");
        DBG_WARN_UNLESS(SearchTxt, L"SearchTxt 为空", L"GMEP", L"2024-01-30");

        m_LegendsListWidget->setHidden(true);
        m_ContentGuideWidget->setHidden(true);
        SearchTxt->blockSignals(true);
        SearchTxt->setText(QString());
        SearchTxt->setEnabled(false);

        UiState = state;
        switch (UiState)
        {
        case gmepgcs::LegendChoosingDialog::NoItems:
            m_ContentGuideWidget->setHidden(false);
            //无图
            m_ContentImageLabel->setPixmap(QPixmap::fromImage(QImage(":/images/Empty/LegendChoosingDialog/EmptyList.png")));
            m_ContentText->setText(QString::fromStdWString(GBMP_TR(L"当前无可供选择的图例")));
            break;

        case gmepgcs::LegendChoosingDialog::NoNetWork:
            m_ContentGuideWidget->setHidden(false);
            //无网
            m_ContentImageLabel->setPixmap(QPixmap::fromImage(QImage(":/images/Empty/LegendChoosingDialog/NoNetwork.png")));
            m_ContentText->setText(QString::fromStdWString(GBMP_TR(L"当前网络不可用")));
            break;

        case gmepgcs::LegendChoosingDialog::FromLocal:
            m_LegendsListWidget->setHidden(false);
            SearchTxt->setEnabled(true);
            SearchTxt->blockSignals(false);
            ClearLegendListWidget();
            ShowLocalLegendContent();
            break;

        case gmepgcs::LegendChoosingDialog::FromPublic:
            m_LegendsListWidget->setHidden(false);
            SearchTxt->setEnabled(true);
            SearchTxt->blockSignals(false);
            ClearLegendListWidget();
            ShowPublicLegendContent();
            break;

        case gmepgcs::LegendChoosingDialog::FromEnterprise:
            m_LegendsListWidget->setHidden(false);
            SearchTxt->setEnabled(true);
            SearchTxt->blockSignals(false);
            ClearLegendListWidget();
            ShowEnterpriseLegnedContent();
            break;
        }

    }

    QLayout * LegendChoosingDialog::InitContentGuideView(QWidget * parent)
    {
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(parent, L"parent为空", L"GMEP", L"2024-01-30");
        auto pLayout = NEW_AS_QT(QVBoxLayout, parent);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pLayout, L"pLayout为空", L"GMEP", L"2024-01-30");
        pLayout->setContentsMargins(0, 0, 0, 0);
        pLayout->setSpacing(5);
        pLayout->setAlignment(Qt::AlignHCenter);
        pLayout->addStretch();

        m_ContentImageLabel = NEW_AS_QT(QLabel, parent);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_ContentImageLabel, L"m_ContentImageLabel为空", L"GMEP", L"2024-01-30");
        pLayout->addWidget(m_ContentImageLabel);
        m_ContentImageLabel->setAlignment(Qt::AlignCenter);
        m_ContentImageLabel->setPixmap(QPixmap::fromImage(QImage(":/images/Empty/LegendChoosingDialog/EmptyList.png")));

        m_ContentText = NEW_AS_QT(QLabel, QString::fromStdWString(GBMP_TR(L"当前无可供选择的图例")), parent);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(m_ContentText, L"m_ContentText为空", L"GMEP", L"2024-01-30");
        pLayout->addWidget(m_ContentText);
        m_ContentText->setAlignment(Qt::AlignCenter);
        m_ContentText->setStyleSheet(
            "QLabel{"
            "font-family:\"Microsoft YaHei\";"
            "font-size:12px;"
            "color:rgba(120, 122, 131, 255);"
            "}"
        );
        pLayout->addStretch();
        return pLayout;
    }

    void LegendChoosingDialog::Resume()
    {
        SetDialogResult(MessageDialogResult::ResultNotSet);
        m_errorMessage.clear();

        m_vCurrLegends = std::vector<std::shared_ptr<ILegend>>();
        m_vLocalLegends = std::vector<std::shared_ptr<ILegend>>();
        m_vPublicLegends = std::vector<std::shared_ptr<ILegend>>();
        m_vEnterpriseLegends = std::vector<std::shared_ptr<ILegend>>();
        m_chosenLegend = nullptr;

        ClearLegendListWidget();
    }


    void LegendChoosingDialog::OnLegendItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
    {
        DBG_WARN_UNLESS(m_LegendsListWidget, L"m_LegendsListWidget 为空", L"GMEP", L"2024-01-30");

        auto childcount = m_LegendsListWidget->count();


        if (previous)
        {
            auto previousItemWidget = m_LegendsListWidget->itemWidget(previous);
            if (previousItemWidget)
            {
                auto legendId = previous->data(Qt::ItemDataRole::UserRole).toString().toStdWString();
                QString selectionMaskName = "SelectionMask" + QString::fromStdWString(legendId);
                auto mask = previousItemWidget->findChild<QLabel*>(selectionMaskName);
                if (mask)
                {
                    mask->setVisible(false);
                }
            }
        }

        if (current)
        {
            auto currentItemWidget = m_LegendsListWidget->itemWidget(current);
            if (currentItemWidget)
            {
                auto legendId = current->data(Qt::ItemDataRole::UserRole).toString().toStdWString();
                QString selectionMaskName = "SelectionMask" + QString::fromStdWString(legendId);
                auto mask = currentItemWidget->findChild<QLabel*>(selectionMaskName);
                if (mask)
                {
                    mask->setVisible(true);
                }
            }
        }

        if (current)
        {
            auto selectedLegendId = current->data(Qt::ItemDataRole::UserRole).toString().toStdWString();

            auto foundLegendItetor = std::find_if(m_vCurrLegends.begin(), m_vCurrLegends.end(),
                [selectedLegendId](std::shared_ptr<ILegend> legend) {
                return legend && ((legend->PlaceholderFrom != 0 ? legend->Uid : gcmp::StringUtil::ToWString(legend->Id)) == selectedLegendId);
            });

            if (foundLegendItetor != m_vCurrLegends.end())
            {
                m_chosenLegend = *foundLegendItetor;
            }
            else
            {
                m_chosenLegend = nullptr;
            }
        }
        else
        {
            m_chosenLegend = nullptr;
        }

        if (OkBtn)
        {
            OkBtn->setEnabled(m_chosenLegend != nullptr);
        }
    }

   
    void LegendChoosingDialog::SetNewtWindowTitle(std::wstring fromLib)
    {
        std::wstring BaseTitle = GBMP_TR(L"选择") + ILegend::GetTypeName(m_legendType);
        QString NewTitle = QString("%1--(%2)").arg(QString::fromStdWString(BaseTitle)).arg(QString::fromStdWString(fromLib));
        setWindowTitle(NewTitle);
    }

    void LegendChoosingDialog::OnSearchBtnClick()
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(SearchTxt, L"SearchTxt为空", L"GMEP", L"2024-01-30");
        std::wstring keyWord = SearchTxt->text().trimmed().toStdWString();
        std::vector<std::shared_ptr<ILegend>> FindLegdens = std::vector<std::shared_ptr<ILegend>>();

        if (keyWord.empty())
        {
            FindLegdens = m_vCurrLegends;
        }
        else
        {
            for (auto &legend : m_vCurrLegends)
            {
                if (!legend)
                {
                    continue;
                }
                if (legend->Name.find(keyWord) != -1)
                {
                    FindLegdens.push_back(legend);
                }
            }
        }

        ClearLegendListWidget();
        if (FindLegdens.empty() || FindLegdens.size() == 0)
        {
            //是否显示无图例那个？
        }
        else
        {
            FillLegendIntoListWidget(FindLegdens);
        }
    }

    std::shared_ptr<ILegend> LegendChoosingDialog::GetChosenLegend()
    {
        return m_chosenLegend;
    }

    void LegendChoosingDialog::AddChosenLegendToLocal()
    {
        if (m_chosenLegend == nullptr)
            return;

        // 若是本地的选择， 无需走这个函数
        if (UiState == FromEnterprise || UiState == FromPublic)
        {
            std::wstring strSrcPngFile = PathUtils::GetThumbnailDownloadFilePath(m_chosenLegend->Thumbnail);
            std::wstring strLocalPngFile = L"";
            // 成功添加到本地后， 将本地png 路径设回m_chosenLegend
            if (ProjectLocalComponentService::Get()->AddChosenLegendToLocal(m_projectId, m_enterpriseId, m_categoryCode, m_chosenLegend.get(), strSrcPngFile, strLocalPngFile, m_isPrivateEnv)
                && !strLocalPngFile.empty())
            {
                if (m_chosenLegend != nullptr)
                    m_chosenLegend->Thumbnail = strLocalPngFile;
                else
                    DBG_WARN(L"AddChosenLegendToLocal（）失败或m_chosenLegend为空", L"GMEP", L"2024-01-30");
            }
            else
                m_chosenLegend = nullptr;// 若选择后下载失败 则认为没选
        }
    }
}